package models

import (
	"context"
	"encoding/json"
	"github.com/olivere/elastic/v7"
	"giv-vue-blog/global"
	"giv-vue-blog/models/ctype"
)

// ArticleModel 文章表
type ArticleModel struct {
	ID        string `json:"id" structs:"id"`                 //es的id
	CreatedAt string `json:"created_at" structs:"created_at"` //创建时间
	UpdatedAt string `json:"updated_at" structs:"updated_at"` //更新时间

	Title    string `json:"title" struct:"title"`                //文章标题
	Keyword  string `json:"keyword,omit(list)" struct:"keyword"` //关键字
	Abstract string `json:"abstract" struct:"abstract"`          //文章简介
	Content  string `json:"content,omit(list)" struct:"content"` //文章内容

	LookCount     int `json:"look_count" structs:"look_count"`         //浏览量
	CommentCount  int `json:"comment_count" structs:"comment_count"`   //评论量
	DiggCount     int `json:"digg_count" structs:"digg_count"`         //点赞量
	CollectsCount int `json:"collects_count" structs:"collects_count"` //收藏量

	UserID       uint   `json:"user_id" structs:"user_id"`               //用户id
	UserNickName string `json:"user_nick_name" structs:"user_nick_name"` //用户昵称
	UserAvatar   string `json:"user_avatar" structs:"user_avatar"`       //用户头像

	Category string `json:"category" structs:"category"`        //文章分类
	Source   string `json:"source,omit(list)" structs:"source"` //文章来源
	Link     string `json:"link,omit(list)" structs:"link"`     //原文链接

	BannerID  uint   `json:"banner_id" structs:"banner_id"`   //文章封面id
	BannerUrl string `json:"banner_url" structs:"banner_url"` //文章封面

	Tags ctype.Array `json:"tags" structs:"tags"` //文章标签
}

func (ArticleModel) Index() string {
	return "article_index" //文章索引
}
func (ArticleModel) Mapping() string {
	return `
	{  "settings":{
      "index":{
		"max_result_window":"1000"
}
},
     "mappings":{
                "properties":{
                        "title":{
                                "type": "text"
                        },
 "keyword":{
                                "type": "keyword"
                        },
"abstract":{
                                "type": "text"
                        },
 "content":{
                                "type": "text"
                        },
                        "user_nick_name":{
                                "type":"keyword"
                        },
  "user_avatar":{
                                "type":"keyword"
                        },
  "category":{
                                "type":"keyword"
                        },
  "source":{
                                "type":"keyword"
                        },
  "link":{
                                "type":"keyword"
                        },
  "banner_url":{
                                "type":"keyword"
                        },
"banner_url":{
                                "type":"keyword"
                        },
                        "user_id":{
                                "type":"integer"
                        },
 "banner_id":{
                                "type":"integer"
                        },
"look_count":{
                                "type":"integer"
                        },
"comment_count":{
                                "type":"integer"
                        },
"digg_count":{
                                "type":"integer"
                        },
"collects_count":{
                                "type":"integer"
                        },
                        "created_at":{
                                "type":"date",
                                "null_value": "null",
                                "format":"[yyyy-MM-dd HH:mm:ss]"
                                },
						"updated_at":{
                                "type":"date",
                                "null_value": "null",
                                "format":"[yyyy-MM-dd HH:mm:ss]"
                                }
                        }
                }
}
`
}

// IndexExists 判断索引是否存在
func (a ArticleModel) IndexExists() bool {

	//判断是否有索引
	exists, err := global.EsClient.IndexExists(a.Index()).Do(context.Background())
	if err != nil {
		global.Log.Error(err.Error())
		return exists
	}
	return exists
}

// CreateIndex 创建索引
func (a ArticleModel) CreateIndex() error {
	if a.IndexExists() {
		//有索引 删掉索引
		_ = a.RemoveIndex()
	}
	//无索引  创建索引
	createIndex, err := global.EsClient.CreateIndex(a.Index()).BodyString(a.Mapping()).Do(context.Background())
	if err != nil {
		global.Log.Error("创建索引失败")
		global.Log.Error(err.Error())
		return err
	}
	if !createIndex.Acknowledged {
		global.Log.Error("创建失败")
		return err
	}
	global.Log.Info("创建索引成功")
	return nil
}

// RemoveIndex 删除索引
func (a ArticleModel) RemoveIndex() error {
	global.Log.Info("索引存在,删除索引")
	//删除索引
	indexDelete, err := global.EsClient.DeleteIndex(a.Index()).Do(context.Background())
	if err != nil {
		global.Log.Error(err.Error())
		return err
	}
	if !indexDelete.Acknowledged {
		global.Log.Error("删除索引失败")
		return err
	}
	global.Log.Info("删除索引成功")
	return nil
}

// Create  添加的方法
func (a *ArticleModel) Create() (err error) {
	indexResponse, err := global.EsClient.Index().
		Index(a.Index()).
		BodyJson(a).Do(context.Background())
	if err != nil {
		global.Log.Error(err.Error())
		return err
	}
	global.Log.Infof("%#v", indexResponse)
	a.ID = indexResponse.Id
	return nil
}

// IsExistData 是否存在该文章
func (a ArticleModel) IsExistData() bool {
	// 查询
	res, err := global.EsClient.
		Search(a.Index()).
		Query(elastic.NewTermQuery("keyword", a.Title)).
		Size(1).
		Do(context.Background())
	if err != nil {
		global.Log.Error(err.Error())
		return false
	}
	if res.Hits.TotalHits.Value > 0 {
		return true
	}
	return false
}

// GetDataByID 通过id判断文章是否存在
func (a *ArticleModel) GetDataByID(id string) error {
	// 查询
	res, err := global.EsClient.
		Get().
		Index(a.Index()).
		Id(id).
		Do(context.Background())
	if err != nil {
		global.Log.Error(err.Error())
		return err
	}
	err = json.Unmarshal(res.Source, a)
	return err
}
